using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Sudoku.Menu;
using System.Diagnostics;
using Services;

namespace Sudoku.GamePlay
{

	/// <summary>
	/// Questa classe in automatico si inserisce nei component del Game, disabilitando qualsiasi altro component che non 
	/// sia l'InputManager. I component vengono tutti ripristinati quando l'utente ha cliccato su unodei due pulsanti visibili,
	/// e la notifica viene automaticamente cancellata e tolta dai component del game.
	/// </summary>
	public class NotifyScreen : ExtendedGameComponent
	{
		public delegate void NotifyEvent(bool response);
		public event NotifyEvent OnResponse;

		private Texture2D bg;
		private Rectangle bgRect;
		private Color bgColor;
		private Texture2D bgImg;
		private Rectangle bgImgRect;
		
		private SpriteFont titleFont;
		private Vector2 titlePos;
		private Color titleColor;
		private String title;
		
		private String mex;
		private List<String> body;
		private SpriteFont bodyFont;
		private List<Vector2> bodypos;

		private const int bodyLnSize = 460;

		private String yesButtonName;
		private String noButtonName;
		private LabelButton yesButton;
		private LabelButton noButton;

		public NotifyScreen(Game game, String title, String mex, String trueButton, String falseButton)
			: base(game)
		{
			this.title = title;
			this.mex = mex;
			this.yesButtonName = trueButton;
			this.noButtonName = falseButton;
			this.DrawOrder = (int)ComponentOrders.UI;

			Game.Components.Add(this); 
		}

		public override void Initialize()
		{
			bg = textureService.Texture("WhiteFill");
			bgRect = new Rectangle(0, 0, 480, 800);
			bgColor = new Color(255, 255, 255, 230);

			bgImg = textureService.Texture("Pellicano");
			bgImgRect = new Rectangle(123, 140, 234, 256);

			foreach (GameComponent c in Game.Components)
				if (!(c is InputManager || c is NotifyScreen )) c.Enabled = false;
		
			var inputService = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
			inputService.OnBack += new InputManager.PhoneButtonEvent(Back);

			titleFont = fontService.Font(FontType.Delicious48);
			titleColor = new Color(102, 0, 51);
			titlePos = new Vector2(240 - (titleFont.MeasureString(title).X * 0.5f), 30);

			bodyFont = fontService.Font(FontType.DeliciousSmallCaps28);
			int totLength = (int)bodyFont.MeasureString(mex).X;

			body = new List<string>();
			bodypos = new List<Vector2>();

			int i = 0;
			while (totLength > bodyLnSize)
			{
				int chars = mex.Length;
				//x should be the string position for a 400 size string
				int x = chars*400/totLength;
				// we look now for a space before the x
				for (int c = x; c > 0; --c )
				{
					if(mex.ElementAt(c) == ' ')
					{
						body.Add(mex.Substring(0,c));
						bodypos.Add(new Vector2(240 - (bodyFont.MeasureString(body[i]).X * 0.5f), 425 + (bodyFont.LineSpacing * i)));
						mex = mex.Substring(c+1);
						totLength = (int)bodyFont.MeasureString(mex).X;
						break;
					}
				}
				i++;
			}

			body.Add(mex);
			bodypos.Add(new Vector2(240 - (bodyFont.MeasureString(mex).X * 0.5f), 425 + (bodyFont.LineSpacing*i)) );

			SpriteFont font = fontService.Font(FontType.Delicious26Bold);

			noButton = new LabelButton(Game, new Rectangle(45, 640, 150, 85), noButtonName, font, Color.White);
			noButton.Texture = textureService.Texture("Button1");
			noButton.OnTap += new Button.ButtonEvent(ExitFalse);
			this.Components.Add(noButton);

			yesButton = new LabelButton(Game, new Rectangle(285, 640, 150, 85), yesButtonName, font, Color.White);
			yesButton.Texture = textureService.Texture("Button1");
			yesButton.OnTap += new Button.ButtonEvent(ExitTrue);
			this.Components.Add(yesButton);

			base.Initialize();
		}

		private void Exit(bool value)
		{
			var inputService = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
			inputService.OnBack -= new InputManager.PhoneButtonEvent(Back);
			
			foreach (GameComponent c in Game.Components)
				c.Enabled = true;

			if (OnResponse != null) OnResponse(value);
			OnResponse = null;
			Game.Components.Remove(this);
			this.Dispose();
		}

		private void ExitFalse(Button sender)
		{
			Exit(false);
		}

		private void ExitTrue(Button sender)
		{
			Exit(true);
		}

		private void Back()
		{
			if (!this.Enabled) return;

			Exit(false);
		}

		public override void Draw(GameTime gameTime)
		{

			spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied);
			spriteBatch.Draw(bg, bgRect, bgColor);
			spriteBatch.End();

			spriteBatch.Begin();
			
			spriteBatch.Draw(bgImg, bgImgRect, Color.White);
			
			spriteBatch.DrawString(titleFont, title, titlePos, titleColor);

			for (int i = 0; i < body.Count; ++i )
			{
				spriteBatch.DrawString(bodyFont, body[i], bodypos[i], titleColor);
			}

			spriteBatch.End();
			
			base.Draw(gameTime);
		}
	}
}
